package com.tian.library.permission

import android.content.Intent
import android.content.pm.PackageManager
import android.os.Bundle
import android.os.Handler
import android.os.Looper
import android.util.SparseBooleanArray
import androidx.fragment.app.Fragment
import androidx.fragment.app.FragmentActivity
import androidx.fragment.app.FragmentManager
import java.util.*

/**
 * @author tiansongtao, Email:tiansongtao@up366.com
 * @date 2020/12/11 10:52
 */
internal class PermissionFragment : Fragment() {


    /**
     * 权限回调对象
     */
    private var mCallback: OnPermissionCallback? = null

    /** 是否申请了特殊权限 */
    private var mSpecialRequest = false

    /**
     * 是否申请了危险权限
     */
    private var mDangerousRequest: Boolean = false

    companion object {
        private const val REQUEST_CODE = "request_code"
        private const val REQUEST_PERMISSION = "permission_group"

        private val requestCodes = SparseBooleanArray()


        fun beginRequest(
            mActivity: FragmentActivity,
            permissions: MutableSet<String>,
            callback: OnPermissionCallback?
        ) {
            val permissionFragment = PermissionFragment()
            val bundle = Bundle()
            var requestCode = 0
            do {
                requestCode = PermissionUtil.getRandomRequestCode()
            } while (requestCodes[requestCode])
            // 标记这个请求码已经被占用
            requestCodes.put(requestCode, true)
            bundle.putInt(REQUEST_CODE, requestCode)
            bundle.putStringArrayList(
                REQUEST_PERMISSION,
                permissions.toMutableList() as ArrayList<String>
            )
            permissionFragment.arguments = bundle
            // 设置保留实例，不会因为配置变化而重新创建
            permissionFragment.retainInstance = true
            // 设置权限回调监听
            permissionFragment.mCallback = callback
            addFragment(mActivity.supportFragmentManager, permissionFragment)
        }

        private fun addFragment(manager: FragmentManager?, fragment: PermissionFragment) {
            manager?.beginTransaction()?.add(fragment, fragment.toString())
                ?.commitAllowingStateLoss()
        }

        private fun removeFragment(manager: FragmentManager?, fragment: PermissionFragment) {
            manager?.beginTransaction()?.remove(fragment)?.commitAllowingStateLoss()
        }

    }

    override fun onResume() {
        super.onResume()
        if (mSpecialRequest) {
            return
        }
        mSpecialRequest = true
        if (mCallback == null) {
            removeFragment(fragmentManager, this)
            return
        }
        requestSpecialPermission()
    }


    override fun onDestroy() {
        super.onDestroy()
        mCallback = null
    }


    /**
     * 申请特殊权限
     */
    private fun requestSpecialPermission() {
        val bundle = arguments
        bundle?.let {
            val allPermissions = it.getStringArrayList(REQUEST_PERMISSION) as MutableList<String>
            allPermissions?.let { per ->
                if (per.isEmpty()) {
                    return
                }

                // 是否需要申请特殊权限
                var requestSpecialPermission = false
                if (PermissionUtil.containsSpecialPermission(per.toMutableSet())) {
                    if (per.contains(PermissionConstant.MANAGE_EXTERNAL_STORAGE) && !PermissionUtil.isGrantedStoragePermission(
                            requireContext()
                        )
                    ) {
                        // 当前必须是 Android 11 及以上版本，因为 hasStoragePermission 在旧版本上是拿旧权限做的判断，所以这里需要多判断一次版本
                        if (PermissionUtil.isHigherAndroid11()) {
                            // 跳转到存储权限设置界面
                            startActivityForResult(
                                PermissionSettingPage.getStoragePermissionIntent(
                                    requireContext()
                                ), it.getInt(REQUEST_CODE)
                            )
                            requestSpecialPermission = true
                        }
                    }

                    if (per.contains(PermissionConstant.REQUEST_INSTALL_PACKAGES) && !PermissionUtil.isGrantedInstallPermission(
                            requireContext()
                        )
                    ) {
                        // 跳转到安装权限设置界面
                        startActivityForResult(
                            PermissionSettingPage.getInstallPermissionIntent(
                                requireContext()
                            ), it.getInt(REQUEST_CODE)
                        )
                        requestSpecialPermission = true
                    }

                    if (per.contains(PermissionConstant.SYSTEM_ALERT_WINDOW) && !PermissionUtil.isGrantedWindowPermission(
                            requireContext()
                        )
                    ) {
                        // 跳转到悬浮窗设置页面
                        startActivityForResult(
                            PermissionSettingPage.getWindowPermissionIntent(
                                requireContext()
                            ), it.getInt(REQUEST_CODE)
                        )
                        requestSpecialPermission = true
                    }

                    if (per.contains(PermissionConstant.NOTIFICATION_SERVICE) && !PermissionUtil.isGrantedNotifyPermission(
                            requireContext()
                        )
                    ) {
                        //跳转到通知栏权限设置页面
                        startActivityForResult(
                            PermissionSettingPage.getNotifyPermissionIntent(
                                requireContext()
                            ), it.getInt(REQUEST_CODE)
                        )
                        requestSpecialPermission = true
                    }

                    if (per.contains(PermissionConstant.WRITE_SETTINGS) && !PermissionUtil.isGrantedSettingPermission(
                            requireContext()
                        )
                    ) {
                        // 跳转到系统设置权限设置页面
                        startActivityForResult(
                            PermissionSettingPage.getSettingPermissionIntent(
                                requireContext()
                            ), it.getInt(REQUEST_CODE)
                        )
                        requestSpecialPermission = true
                    }

                }

                // 当前必须没有跳转到悬浮窗或者安装权限界面
                if (!requestSpecialPermission) {
                    requestDangerousPermission()
                }
            }
        }
    }

    /**
     * 申请危险权限
     */
    private fun requestDangerousPermission() {
        val bundle = arguments
        bundle?.let {
            val allPermissions = it.getStringArrayList(REQUEST_PERMISSION) as MutableList<String>
            allPermissions?.let { per ->
                if (per.isEmpty()) {
                    return
                }
                val localPermissions = mutableSetOf<String>()
                // Android 10 定位策略发生改变，申请后台定位权限的前提是要有前台定位权限（授予了精确或者模糊任一权限）
                if (PermissionUtil.isHigherAndroid11() && per.contains(PermissionConstant.ACCESS_BACKGROUND_LOCATION)) {
                    if (per.contains(PermissionConstant.ACCESS_COARSE_LOCATION) && !PermissionUtil.isGrantedPermission(
                            requireContext(),
                            PermissionConstant.ACCESS_COARSE_LOCATION
                        )
                    ) {
                        localPermissions.add(PermissionConstant.ACCESS_COARSE_LOCATION)
                    }
                    if (per.contains(PermissionConstant.ACCESS_FINE_LOCATION) && !PermissionUtil.isGrantedPermission(
                            requireContext(),
                            PermissionConstant.ACCESS_FINE_LOCATION
                        )
                    ) {
                        localPermissions.add(PermissionConstant.ACCESS_FINE_LOCATION)
                    }

                }

                // 如果不需要申请前台定位权限就直接申请危险权限
                if (localPermissions.isEmpty()) {
                    requestPermissions(per.toTypedArray(), it.getInt(REQUEST_CODE))
                    return
                }

                if (activity == null) {
                    return
                }

                beginRequest(activity!!, localPermissions, object : OnPermissionCallback {
                    override fun onGranted(permissions: MutableSet<String>, all: Boolean) {
                        if (!all || !isAdded || arguments == null) {
                            return
                        }

                        requestPermissions(
                            allPermissions.toTypedArray(),
                            arguments!!.getInt(REQUEST_CODE)
                        )
                    }

                    override fun onDenied(permissions: MutableSet<String>, never: Boolean) {
                        if (!isAdded || arguments == null) {
                            return
                        }
                        requestPermissions(
                            allPermissions.toTypedArray(),
                            arguments!!.getInt(REQUEST_CODE)
                        )
                    }

                })
            }
        }
    }


    override fun onRequestPermissionsResult(
        requestCode: Int,
        permissions: Array<out String>,
        grantResults: IntArray
    ) {
        if (arguments == null || requestCode != arguments!!.getInt(REQUEST_CODE)) {
            return
        }
        val callback = mCallback
        mCallback = null
        if (callback == null) {
            return
        }
        for (index in permissions.indices) {
            val permission = permissions[index]
            if (PermissionUtil.isSpecialPermission(permission)) {
                // 如果这个权限是特殊权限，那么就重新进行权限检测
                grantResults[index] =
                    PermissionUtil.getPermissionStatus(requireContext(), permission)
                continue
            }

            if (PermissionUtil.isHigherAndroid11() && PermissionConstant.ACCESS_BACKGROUND_LOCATION == permission) {
                // 这个权限是后台定位权限并且当前手机版本是 Android 11 及以上，那么就需要重新进行检测
                // 因为只要申请这个后台定位权限，grantResults 数组总对这个权限申请的结果返回 -1（拒绝）
                grantResults[index] =
                    PermissionUtil.getPermissionStatus(requireContext(), permission)
                continue
            }

            if (!PermissionUtil.isHigherAndroid10()) {
                // 重新检查 Android 10.0 的三个新权限
                if (PermissionConstant.ACCESS_BACKGROUND_LOCATION == permission || PermissionConstant.ACTIVITY_RECOGNITION == permission || PermissionConstant.ACCESS_MEDIA_LOCATION == permission) {
                    // 如果当前版本不符合最低要求，那么就重新进行权限检测
                    grantResults[index] =
                        PermissionUtil.getPermissionStatus(requireContext(), permission)
                    continue
                }
            }

            if (!PermissionUtil.isHigherAndroid9()) {
                // 重新检查 Android 9.0 的一个新权限
                if (PermissionConstant.ACCEPT_HANDOVER == permission) {
                    // 如果当前版本不符合最低要求，那么就重新进行权限检测
                    grantResults[index] =
                        PermissionUtil.getPermissionStatus(requireContext(), permission)
                }
            }

            if (!PermissionUtil.isHigherAndroid8()) {
                // 重新检查 Android 8.0 的两个新权限
                if (PermissionConstant.ANSWER_PHONE_CALLS == permission || PermissionConstant.READ_PHONE_NUMBERS == permission) {
                    // 如果当前版本不符合最低要求，那么就重新进行权限检测
                    grantResults[index] =
                        PermissionUtil.getPermissionStatus(requireContext(), permission)
                }
            }
        }

        // 释放对这个请求码的占用
        requestCodes.delete(requestCode)
        // 将 Fragment 从 Activity 移除
        removeFragment(fragmentManager, this)

        // 获取已授予的权限
        var deniedPermissions = mutableSetOf<String>()
        var grantedPermissions = mutableSetOf<String>()
        for (index in grantResults.indices) {
            if (grantResults[index] == PackageManager.PERMISSION_DENIED) {
                deniedPermissions.add(permissions[index])
            } else {
                grantedPermissions.add(permissions[index])
            }
        }

        if (grantedPermissions.size == permissions.size) {
            // 代表申请的所有的权限都授予了
            callback?.onGranted(permissions.toMutableSet(), true)
        } else {
            if (grantedPermissions.size == 0) {
                callback?.onGranted(grantedPermissions, false)
            }
            callback?.onDenied(deniedPermissions, PermissionUtil.isPermissionPermanentDenied(requireActivity(), deniedPermissions))
        }
    }


    override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
        if (arguments == null) {
            return
        }

        if (!mDangerousRequest && requestCode == arguments!!.getInt(REQUEST_CODE)) {
            mDangerousRequest = true
            // 需要延迟执行，不然有些华为机型授权了但是获取不到权限
            Handler(Looper.getMainLooper()).postDelayed({
                // 如果用户离开太久，会导致 Activity 被回收掉
                // 所以这里要判断当前 Fragment 是否有被添加到 Activity
                // 可在开发者模式中开启不保留活动来复现这个 Bug
                if (!isAdded) {
                    return@postDelayed
                }
                // 请求其他危险权限
                // 请求其他危险权限
                requestDangerousPermission()
            }, 300)
        }

    }


}